package com.suxin.utils;

import org.springframework.lang.Nullable;
import org.springframework.util.PropertyPlaceholderHelper;

import java.text.MessageFormat;
import java.util.Map;
import java.util.Objects;

/**
 * @author Tang
 * @classname PropertySourcesHolderUtils
 * @description [ 内容占位符替换 ]
 * spring 装饰的 PropertySources  PropertySourcesPlaceholderConfigurer
 * spring 实现的 PropertySourcesPlaceholdersResolver
 * @date 2021/12/23 11:07
 */
public class PropertySourcesHolderUtils {

    private static final String PLACE_HOLDER_PREFIX = "{$";

    private static final String PLACE_HOLDER_ENDFIX = "}";

    private static final PropertyPlaceholderHelper PROPERTY_PLACEHOLDER_HELPER = new PropertyPlaceholderHelper(
            PLACE_HOLDER_PREFIX, PLACE_HOLDER_ENDFIX
    );

    private static CustomizePlaceHolderResolver resolver;

    // 单例
    private static PropertySourcesHolderUtils contextHolderUtils;

    private PropertySourcesHolderUtils(final Map<String, String> paramMap) {
        PropertySourcesHolderUtils.resolver = new CustomizePlaceHolderResolver(paramMap);
    }

    /**
     * 实例获取
     * @param paramMap
     * @return
     */
    public static PropertySourcesHolderUtils getContextHolder(final Map<String, String> paramMap) {
        if (Objects.isNull(contextHolderUtils)) {
            contextHolderUtils = new PropertySourcesHolderUtils(paramMap);
        }
        return contextHolderUtils;
    }

    /**
     * 字符串解析
     * @param template
     * @return
     */
    public static String replacePlaceHolder(final String template) {
        return PROPERTY_PLACEHOLDER_HELPER.replacePlaceholders(template, resolver);
    }

    public static class CustomizePlaceHolderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {

        private final Map<String, String> paramMap;

        public CustomizePlaceHolderResolver(Map<String, String> paramMap) {
            this.paramMap = paramMap;
        }

        @Nullable
        @Override
        public String resolvePlaceholder(String placeholderName) {
            String value = paramMap.get(placeholderName);
            if (value == null) {
                String errorStr = MessageFormat.format("template:{} require param:{},but no exist! paramMap:{}",
                        placeholderName, paramMap.toString());
                throw new IllegalArgumentException(errorStr);
            }
            return null;
        }
    }

}